﻿//-----------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" author="Artak Mkrtchyan">
//     Creative Commons - GNU General Public License (http://creativecommons.org/licenses/GPL/2.0/
// </copyright>
// <author>Artak Mkrtchyan</author>
// <email>mkArtak@gmail.com</email>
// <date>15/07/2012</date>
//-----------------------------------------------------------------------

using ConsoleHoster.Common.Model;
using ConsoleHoster.Common.UserInput;
using ConsoleHoster.Common.Utilities;
using ConsoleHoster.Common.Utilities.Threading;
using ConsoleHoster.View.Popups;
using ConsoleHoster.ViewModel;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace ConsoleHoster.View
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private readonly ILogger logger;
        private readonly ConsoleHostViewModel viewModel;

        private AboutView aboutView = null;

        public MainWindow(ILogger argLogger)
        {
            InitializeComponent();

            try
            {
                this.logger = argLogger ?? EmptyLogger.Instance;

                //TODO: Uncomment and use the following log path under User's local AppData folder.
                //string tmpUserAppDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                //this.logger = new SimpleFileLogger(Path.Combine(tmpUserAppDataFolder, "ConsoleHoster", "Log"));
                ViewModelDispatcher tmpDispatcher = new ViewModelDispatcher(this.Dispatcher);
                this.viewModel = new ConsoleHostViewModel(
                    tmpDispatcher,
                    new ViewSettings(this, this.FindResource("PopupStyle") as Style),
                    this.logger);
                this.DataContext = this.viewModel;
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ToString());
                this.Close();
            }
        }

        public MainWindow()
            : this(null)
        {

        }

        private void ImportShortcut_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.ImportShortcut();
        }

        private void ImportProjects_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.ImportProjects();
        }

        private void ExportProjects_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.ExportProjects();
        }

        private void ExportShortcut_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.ExportCurrentProjectShortcut();
        }

        private async void NewProject_Click(object sender, RoutedEventArgs e)
        {
            await this.ViewModel.CreateNewProjectAsync();
        }

        private void EditProject_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.EditActiveProject();
        }

        private void ProjectsManager_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.ConfigureProjectsList();
        }

        private void MenuHelpAbout_Click(object sender, RoutedEventArgs e)
        {
            this.aboutView = new AboutView(this.ViewModel.CurrentAssemblyVersion);
            this.aboutView.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
            this.aboutView.Owner = this;
            this.aboutView.ShowDialog();
            this.aboutView = null;
        }

        private void MenuHelpUpdate_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.CheckForUpdates();
        }

        private void MenuOnlineHelp_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Process.Start("http://consolehoster.codeplex.com/documentation");
            }
            catch (Exception ex)
            {
                this.logger.LogError("Error while opening user guide. Details: {0}", ex.ToString());
            }
        }

        private void DeleteProject_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.RemoveActiveProject();
        }

        private void OpenOutput_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.OpenOutputLogForActiveProject();
        }

        private void TryBreakExecution_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.ActiveConsole.BreakExecution();
        }

        private async void FontMenu_Click(object sender, RoutedEventArgs e)
        {
            await this.ViewModel.SelectFontSettingsAsync();
        }

        private void DuplicateProject_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.DuplicateCurrentProject();
        }

        private void RunInExternalConsole_Click(object sender, RoutedEventArgs e)
        {
            this.ViewModel.RunInExternalConsole();
        }

        private async void GlobalCommands_Click(object sender, RoutedEventArgs e)
        {
            await this.ViewModel.UpdateGlobalCommands();
        }

        private void Window_Closing_1(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (this.ViewModel != null)
            {
                this.ViewModel.Dispose();
            }
        }

        private void Window_Activated_1(object sender, EventArgs e)
        {
            this.ActivateIfIUserDataRequester(this.ViewModel.FontSettingsProvider as IUserDataRequester);
            this.ActivateIfIUserDataRequester(this.ViewModel.GlobalCommandsProvider as IUserDataRequester);
            this.ActivateIfIUserDataRequester(this.ViewModel.ProjectsManager as IUserDataRequester);

            this.ActivateWindowIfNotNull(this.aboutView);
        }

        private void MainWindow_PreviewKeyDown_1(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (this.ViewModel.KeyboardInputHandler.HandleKeyboardInput(e.Key, null))
            {
                e.Handled = true;
            }
        }

        private async void MainWindow_Loaded_1(object sender, RoutedEventArgs e)
        {
            SplashWindow.EndSplash();

            if (await this.ViewModel.LoadAsync())
            {
                this.RegisterKeyboardInputHandlers();
            }
        }

        private void RegisterKeyboardInputHandlers()
        {
            IKeyboardInputHandler argKeyboardInputHandler = this.viewModel.KeyboardInputHandler;
            if (argKeyboardInputHandler != null)
            {
                argKeyboardInputHandler.RegisterHandler(Key.Tab, new[] { Key.LeftCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.SwitchToConsole(!ksp.AnyOfKeysDown(Key.LeftShift, Key.RightShift));

                        return true;
                    }
                    return false;
                });
                argKeyboardInputHandler.RegisterHandler(Key.Tab, new[] { Key.RightCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.SwitchToConsole(!ksp.AnyOfKeysDown(Key.LeftShift, Key.RightShift));
                        return true;
                    }
                    return false;
                });
                argKeyboardInputHandler.RegisterHandler(Key.W, new[] { Key.LeftCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.ActiveConsole.Close();
                        return true;
                    }
                    return false;
                });
                argKeyboardInputHandler.RegisterHandler(Key.W, new[] { Key.RightCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.ActiveConsole.Close();
                        return true;
                    }
                    return false;
                });
                argKeyboardInputHandler.RegisterHandler(Key.F, new[] { Key.LeftCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.ActiveConsole.SearchVM.SearchEnabled = true;
                        return true;
                    }
                    return false;
                });
                argKeyboardInputHandler.RegisterHandler(Key.F, new[] { Key.RightCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.ActiveConsole.SearchVM.SearchEnabled = true;
                        return true;
                    }
                    return false;
                });
                argKeyboardInputHandler.RegisterHandler(Key.E, new[] { Key.LeftCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.ActiveConsole.ShowExplorerPane = !this.ViewModel.ActiveConsole.ShowExplorerPane;
                        return true;
                    }
                    return false;
                });
                argKeyboardInputHandler.RegisterHandler(Key.E, new[] { Key.RightCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.ActiveConsole.ShowExplorerPane = !this.ViewModel.ActiveConsole.ShowExplorerPane;
                        return true;
                    }
                    return false;
                });
                argKeyboardInputHandler.RegisterHandler(Key.D, new[] { Key.LeftCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.ActiveConsole.ShowCommandsPane = !this.ViewModel.ActiveConsole.ShowCommandsPane;
                        return true;
                    }
                    return false;
                });
                argKeyboardInputHandler.RegisterHandler(Key.D, new[] { Key.RightCtrl }, null, ksp =>
                {
                    if (this.ViewModel.ActiveConsole != null)
                    {
                        this.ViewModel.ActiveConsole.ShowCommandsPane = !this.ViewModel.ActiveConsole.ShowCommandsPane;
                        return true;
                    }
                    return false;
                });
            }
        }

        private void ActivateIfIUserDataRequester(IUserDataRequester argRequester)
        {
            if (argRequester != null)
            {
                this.ActivateWindowIfNotNull(argRequester.View);
            }
        }

        private void ActivateWindowIfNotNull(Window argWindow)
        {
            if (argWindow != null)
            {
                argWindow.Activate();
            }
        }

        private ConsoleHostViewModel ViewModel
        {
            get
            {
                return this.viewModel;
            }
        }
    }
}